

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>OSD 故障排除 &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
        <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/doctools.js"></script>
        <script src="../../../_static/sphinx_highlight.js"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../genindex/" />
    <link rel="search" title="Search" href="../../../search/" />
    <link rel="next" title="归置组排障" href="../troubleshooting-pg/" />
    <link rel="prev" title="监视器故障排除" href="../troubleshooting-mon/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../../../" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="../../">Ceph 存储集群</a></li>
          <li class="breadcrumb-item"><a href="../../operations/">集群运维</a></li>
      <li class="breadcrumb-item active">OSD 故障排除</li>
      <li class="wy-breadcrumbs-aside">
            <a href="../../../_sources/rados/troubleshooting/troubleshooting-osd.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../../" class="icon icon-home"> Ceph
          

          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../start/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephadm/">Cephadm</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../">Ceph 存储集群</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../configuration/">配置</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../operations/">运维</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../man/">    手册页</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../">故障排除</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../community/">Ceph 社区</a></li>
<li class="toctree-l3"><a class="reference internal" href="../log-and-debug/">日志记录和调试</a></li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting-mon/">监视器故障排除</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">OSD 故障排除</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#id2">收集 OSD 数据</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id6">在不引起重均衡的情况下停机</a></li>
<li class="toctree-l4"><a class="reference internal" href="#osd-not-running">OSD 没运行</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id12">OSD 龟速或无响应</a></li>
<li class="toctree-l4"><a class="reference internal" href="#rados-tshooting-flapping-osd">状态抖动的 OSD</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting-pg/">归置组排障</a></li>
<li class="toctree-l3"><a class="reference internal" href="../memory-profiling/">内存剖析</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cpu-profiling/">CPU 剖析</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../api/">APIs</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../monitoring/">监控概览</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dev/developer_guide/">开发者指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dev/internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../hardware-monitoring/">硬件监控</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <section id="osd">
<h1>OSD 故障排除<a class="headerlink" href="#osd" title="Permalink to this heading"></a></h1>
<p>对集群的 OSD 排障前，先检查一下各监视器和网络。</p>
<p>首先，确定一下监视器们是否形成了法定人数。
执行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span></code> 或 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">-s</span></code> 命令，
如果 Ceph 返回的是 <code class="docutils literal notranslate"><span class="pre">HEALTH_OK</span></code> 说明形成了监视器法定人数。</p>
<p>如果监视器没形成法定人数、或者监视器状态有错误，
继续下一步之前需要参考<a class="reference external" href="../troubleshooting-mon">监视器故障排除</a>资料先解决监视器问题。</p>
<p>接下来，核实下你的网络，确保它在正常运行，
因为网络对 OSD 的正常运作和性能有显著影响，
检查一下主机侧的丢包情况和交换机侧的 CRC 错误。</p>
<section id="id2">
<h2>收集 OSD 数据<a class="headerlink" href="#id2" title="Permalink to this heading"></a></h2>
<p>在对 OSD 进行故障排除时，收集有关 OSD 的各种信息非常有用。
有些信息来自<a class="reference external" href="../../operations/monitoring-osd-pg">监控 OSD</a> 的实践
（例如，运行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">osd</span> <span class="pre">tree</span></code> 命令获得的）。
其他信息与集群的拓扑结构有关，将在以下章节中讨论。</p>
<section id="ceph">
<h3>Ceph 日志<a class="headerlink" href="#ceph" title="Permalink to this heading"></a></h3>
<p>Ceph 日志文件存储在 <code class="docutils literal notranslate"><span class="pre">/var/log/ceph</span></code> 下。除非路径改掉了
（或者你的是容器化环境，它会把日志存到别处），
日志文件可以用如下命令罗列：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><style type="text/css">
span.prompt1:before {
  content: "$ ";
}
</style><span class="prompt1">ls<span class="w"> </span>/var/log/ceph</span>
</pre></div></div><p>如果看到的日志还不够详细，可以更改日志级别。
参考<a class="reference external" href="../log-and-debug">日志记录和调试</a>，
确保能看到适当的日志，同时又不影响集群运行。</p>
</section>
<section id="id3">
<h3>管理套接字<a class="headerlink" href="#id3" title="Permalink to this heading"></a></h3>
<p>用管理套接字检索运行时信息。首先，
罗列一下 Ceph 守护进程的套接字，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ls<span class="w"> </span>/var/run/ceph</span>
</pre></div></div><p>然后，执行下列命令（把 <code class="docutils literal notranslate"><span class="pre">{daemon-name}</span></code>
替换成指定守护进程的名字比如如 <code class="docutils literal notranslate"><span class="pre">osd.0</span></code> ）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>daemon<span class="w"> </span><span class="o">{</span>daemon-name<span class="o">}</span><span class="w"> </span><span class="nb">help</span></span>
</pre></div></div><p>另外，也可以指定一个 <code class="docutils literal notranslate"><span class="pre">{socket-file}</span></code> 执行命令
（ socket-file 套接字文件是 <code class="docutils literal notranslate"><span class="pre">/var/run/ceph</span></code> 下的一个特殊文件）：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>daemon<span class="w"> </span><span class="o">{</span>socket-file<span class="o">}</span><span class="w"> </span><span class="nb">help</span></span>
</pre></div></div><p>通过管理套接字可以实现很多任务，包括：</p>
<ul class="simple">
<li><p>在运行时列出 Ceph 配置</p></li>
<li><p>列出历史操作</p></li>
<li><p>列出操作的优先队列状态</p></li>
<li><p>列出正在进行的操作</p></li>
<li><p>列出性能计数器</p></li>
</ul>
</section>
<section id="id4">
<h3>显示剩余空间<a class="headerlink" href="#id4" title="Permalink to this heading"></a></h3>
<p>文件系统可能会出现问题。要显示文件系统剩余空间，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">df<span class="w"> </span>-h</span>
</pre></div></div><p>此命令的其它用法和选项见 <code class="docutils literal notranslate"><span class="pre">df</span> <span class="pre">--help</span></code> 。</p>
</section>
<section id="i-o">
<h3>I/O 统计信息<a class="headerlink" href="#i-o" title="Permalink to this heading"></a></h3>
<p>用 <a class="reference external" href="https://en.wikipedia.org/wiki/Iostat">iostat</a> 工具定位 I/O 相关的问题。执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">iostat<span class="w"> </span>-x</span>
</pre></div></div></section>
<section id="id5">
<h3>诊断消息<a class="headerlink" href="#id5" title="Permalink to this heading"></a></h3>
<p>要查看内核里的诊断信息，配合 <code class="docutils literal notranslate"><span class="pre">less</span></code> 、 <code class="docutils literal notranslate"><span class="pre">more</span></code> 、 <code class="docutils literal notranslate"><span class="pre">grep</span></code> 或
<code class="docutils literal notranslate"><span class="pre">tail</span></code> 执行 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 命令，例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">dmesg<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>scsi</span>
</pre></div></div></section>
</section>
<section id="id6">
<h2>在不引起重均衡的情况下停机<a class="headerlink" href="#id6" title="Permalink to this heading"></a></h2>
<p>有时不得不维修集群的一小部分、
或解决某个故障域的问题（如一机架）。
不过，当您停止 OSD 进行维护时，
可能不想让 CRUSH 自动重均衡集群。
要避免这种重均衡行为，可执行以下命令把集群设置为 <code class="docutils literal notranslate"><span class="pre">noout</span></code> ：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">set</span><span class="w"> </span>noout</span>
</pre></div></div><div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>这只是一个思想实验，目的是让读者对故障域和
CRUSH 行为有所了解，而不是建议用 Luminous 以上版本的人只要会执行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">osd</span> <span class="pre">set</span> <span class="pre">noout</span></code> 命令就行了。
当 OSD 恢复到 <code class="docutils literal notranslate"><span class="pre">up</span></code> 状态时，重均衡将恢复运行，
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">osd</span> <span class="pre">set</span> <span class="pre">noout</span></code> 命令引入的更改也将回退。</p>
</div>
<p>在 Luminous 或更高版本上，可以只在受影响的 OSD 上设置此标记，
这样更安全。要给指定 OSD 增加或删除 <code class="docutils literal notranslate"><span class="pre">noout</span></code> 标记，
可以执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>add-noout<span class="w"> </span>osd.0</span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>rm-noout<span class="w">  </span>osd.0</span>
</pre></div></div><p>也可以一次设置整个 CRUSH 桶。比如，
你准备关闭 <code class="docutils literal notranslate"><span class="pre">prod-ceph-data1701</span></code> 来扩容内存，
可以执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>set-group<span class="w"> </span>noout<span class="w"> </span>prod-ceph-data1701</span>
</pre></div></div><p>设置此标记后，就可以停止 OSD 、还有失败域内共存的其它需要维护的 Ceph 服务：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">systemctl</span> <span class="n">stop</span> <span class="n">ceph</span>\<span class="o">*.</span><span class="n">service</span> <span class="n">ceph</span>\<span class="o">*.</span><span class="n">target</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>一个 OSD 停机后，此 OSD 内的所有归置组都会被标记为 <code class="docutils literal notranslate"><span class="pre">degraded</span></code> 。</p>
</div>
<p>维护结束后，重启 OSD 和其它停掉的守护进程们。
不过，如果维护期间重启过主机，
无需重启它们应该就会自己回归。
要重启 OSD 或其他守护进程，
执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">sudo<span class="w"> </span>systemctl<span class="w"> </span>start<span class="w"> </span>ceph.target</span>
</pre></div></div><p>最后，必须解除集群范围的 <code class="docutils literal notranslate"><span class="pre">noout</span></code> 标志，
执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">unset</span><span class="w"> </span>noout</span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>unset-group<span class="w"> </span>noout<span class="w"> </span>prod-ceph-data1701</span>
</pre></div></div><p>很多当代 Linux 发行版都采用了 <code class="docutils literal notranslate"><span class="pre">systemd</span></code> 做服务管理。
然而，对于某些操作系统（特别是比较老的），
你可能得用等价的 <code class="docutils literal notranslate"><span class="pre">service</span></code> 或 <code class="docutils literal notranslate"><span class="pre">start</span></code>/<code class="docutils literal notranslate"><span class="pre">stop</span></code> 命令。</p>
</section>
<section id="osd-not-running">
<span id="id7"></span><h2>OSD 没运行<a class="headerlink" href="#osd-not-running" title="Permalink to this heading"></a></h2>
<p>通常情况下，重启 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 守护进程后，它可以重回集群并恢复。</p>
<section id="id8">
<h3>OSD 起不来<a class="headerlink" href="#id8" title="Permalink to this heading"></a></h3>
<p>如果启动集群后，其中一个 OSD 起不来，依次检查：</p>
<ul>
<li><p><strong>配置文件：</strong> 如果你新装的 OSD 不能启动，
检查下配置文件，确保它合爻性
（比如 <code class="docutils literal notranslate"><span class="pre">host</span></code> 而非 <code class="docutils literal notranslate"><span class="pre">hostname</span></code> ，等等）；</p></li>
<li><p><strong>检查各种路径：</strong> 检查你配置的路径，
对应的数据和元数据路径是否都存在
（比如日志路径、 WAL 、 DB ）。
分离开 OSD 数据和元数据，看看配置文件和实际挂载点是否存在出入。
如果有，这些错误可能就是 OSD 不能启动的原因。
可以把元数据存储在一个独立的块设备、分区、
或 LVM 管理的驱动器上，并给每个 OSD 分别分配一个分区。</p></li>
<li><p><strong>检查最大线程数：</strong> 如果集群内有的节点 OSD 数量非常多，
也许会达到到默认的最大线程数限制（通常是 32000 个），
尤其是在恢复期间更可能发生。
把最大线程数更改为支持的最大值（即 4194303 ），
也许能解决此问题。要把线程数改成最大值，
执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">sysctl<span class="w"> </span>-w<span class="w"> </span>kernel.pid_max<span class="o">=</span><span class="m">4194303</span></span>
</pre></div></div><p>如果增大最大线程数解决了这个问题，你可以把此配置
<code class="docutils literal notranslate"><span class="pre">kernel.pid_max</span></code> 写入 <code class="docutils literal notranslate"><span class="pre">/etc/sysctl.d</span></code> 内的文件或写入主配置 <code class="docutils literal notranslate"><span class="pre">/etc/sysctl.conf</span></code> ，使之永久生效，
例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">kernel</span><span class="o">.</span><span class="n">pid_max</span> <span class="o">=</span> <span class="mi">4194303</span>
</pre></div>
</div>
</li>
<li><p><strong>检查 ``nf_conntrack``:</strong> 这个连接跟踪和连接限制系统
是许多 Ceph 生产集群问题的祸根，这些问题常常是缓慢且潜移默化地发生。
随着集群的拓扑结构和客户端载荷的增长，
奇怪且间歇性的连接故障和性能问题发生得越来越多，
特别是在一天中的某个时间会更糟。要定位此类问题，
先检查 <code class="docutils literal notranslate"><span class="pre">syslog</span></code> 历史记录，看是否有 “table full” （表填满）事件。
定位此类问题的其中一个方法如下：首先，
用 <code class="docutils literal notranslate"><span class="pre">sysctl</span></code> 命令给 <code class="docutils literal notranslate"><span class="pre">nf_conntrack_max</span></code> 赋予一个非常大的值。
然后，提高 <code class="docutils literal notranslate"><span class="pre">nf_conntrack_buckets</span></code> 的数值，使得
<code class="docutils literal notranslate"><span class="pre">nf_conntrack_buckets</span></code> x 8 = <code class="docutils literal notranslate"><span class="pre">nf_conntrack_max</span></code> ；
这一步可能需要在 <code class="docutils literal notranslate"><span class="pre">sysctl</span></code> 之外操作，（例如
<code class="docutils literal notranslate"><span class="pre">&quot;echo</span> <span class="pre">131072</span> <span class="pre">&gt;</span> <span class="pre">/sys/module/nf_conntrack/parameters/hashsize</span></code> ）。
另外一种定位此问题的方法是把相关的内核模块加入黑名单，
防止它们一起处理。此方法很有效，但也很脆弱。
涉及的模块及其顺序因内核版本不同可能差别很大。
即使加了黑名单， <code class="docutils literal notranslate"><span class="pre">iptables</span></code> 或 <code class="docutils literal notranslate"><span class="pre">docker</span></code>
有时仍然会激活连接跟踪，
所以我们建议对这种调整采用 “设置后不管” 策略。
在现代系统中，这不会消耗太多资源。</p></li>
<li><p><strong>内核版本：</strong> 确认在用的内核版本以及所用的发布版。
默认情况下， Ceph 会使用一些第三方工具，这些工具可能有缺陷或者与特定发行版或内核版本产生冲突
（如 Google 的 <code class="docutils literal notranslate"><span class="pre">gperftools</span></code> 和 <code class="docutils literal notranslate"><span class="pre">TCMalloc</span></code> ）。
检查下<a class="reference external" href="../../../start/os-recommendations">操作系统推荐</a>和各 Ceph 版本的发布说明，
以确保已经解决了内核相关的问题。</p></li>
<li><p><strong>段错误：</strong> 如果出现了段错误，提高日志级别并重启有问题的守护进程。
如果段错误重现了，搜索一下 Ceph 缺陷追踪器
<a class="reference external" href="https://tracker.ceph.com/projects/ceph/">https://tracker.ceph/com/projects/ceph</a> 和
<code class="docutils literal notranslate"><span class="pre">dev</span></code> 、 <code class="docutils literal notranslate"><span class="pre">ceph-users</span></code> 邮件列表归档
<a class="reference external" href="https://ceph.io/resources">https://ceph.io/resources</a> ，
看看别人是否也遇到并报告过同样的问题。
如果它真是一个新的、唯一的故障案例，把它发到 <code class="docutils literal notranslate"><span class="pre">dev</span></code> 邮件列表，
并提供这些信息：运行的 Ceph 具体版本号、
<code class="docutils literal notranslate"><span class="pre">ceph.conf</span></code> （把密钥用 XXX 替换掉）、
你的监视器状态输出、和相关的日志文件节选。</p></li>
</ul>
</section>
<section id="id9">
<h3>OSD 故障<a class="headerlink" href="#id9" title="Permalink to this heading"></a></h3>
<p>某个 OSD 发生故障时，这意味着一个 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 进程没有响应或者已经死亡，
而且对应的 OSD 已经被标记成了 <code class="docutils literal notranslate"><span class="pre">down</span></code> 状态。
活着的 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 守护进程们会报告给各监视器，
说它挂了，随后它就会浮现在 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span></code> 命令的新状态信息里，如下例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>health</span>
</pre></div></div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">HEALTH_WARN</span> <span class="mi">1</span><span class="o">/</span><span class="mi">3</span> <span class="ow">in</span> <span class="n">osds</span> <span class="n">are</span> <span class="n">down</span>
</pre></div>
</div>
<p>只要有一个或多个 OSD 被标记为 <code class="docutils literal notranslate"><span class="pre">in</span></code> 且 <code class="docutils literal notranslate"><span class="pre">down</span></code> ，
就会产生这样的健康告警。要查出哪个 OSD 是 <code class="docutils literal notranslate"><span class="pre">down</span></code> 的，
给命令加上 <code class="docutils literal notranslate"><span class="pre">detail</span></code> ，如下例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>health<span class="w"> </span>detail</span>
</pre></div></div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">HEALTH_WARN</span> <span class="mi">1</span><span class="o">/</span><span class="mi">3</span> <span class="ow">in</span> <span class="n">osds</span> <span class="n">are</span> <span class="n">down</span>
<span class="n">osd</span><span class="mf">.0</span> <span class="ow">is</span> <span class="n">down</span> <span class="n">since</span> <span class="n">epoch</span> <span class="mi">23</span><span class="p">,</span> <span class="n">last</span> <span class="n">address</span> <span class="mf">192.168.106.220</span><span class="p">:</span><span class="mi">6800</span><span class="o">/</span><span class="mi">11080</span>
</pre></div>
</div>
<p>或者，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>tree<span class="w"> </span>down</span>
</pre></div></div><p>如果有个驱动器发生故障或其它错误使
<code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 不能正常运行或重启，应该会有一条错误信息出现在 <code class="docutils literal notranslate"><span class="pre">/var/log/ceph/</span></code> 内的日志文件里。</p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 守护进程因心跳故障、
<code class="docutils literal notranslate"><span class="pre">suicide</span> <span class="pre">timeout</span></code> 错误停止，
其原因可能是底层驱动器或文件系统无响应。
查看一下 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 和 <cite>syslog</cite> 输出，找一下驱动器错误或内核错误。
可能得加一些选项（例如 <code class="docutils literal notranslate"><span class="pre">dmesg</span> <span class="pre">-T</span></code> 显示容易看懂的时间戳），
以免把旧错误消息误读成新的。</p>
<p>如果整个主机的 OSD 都是 <code class="docutils literal notranslate"><span class="pre">down</span></code> ，检查一下，
看是不是主机网络错误或硬件问题。</p>
<p>如果这个 OSD 问题是软件错误（比如，
失败的断言或其它意外错误），搜索一下有没有人报告过这个问题，
在 <a class="reference external" href="https://tracker.ceph/com/projects/ceph">bug tracker</a> 、
<a class="reference external" href="https://lists.ceph.io/hyperkitty/list/dev&#64;ceph.io/">开发邮件列表存档</a> 、
和 <a class="reference external" href="https://lists.ceph.io/hyperkitty/list/ceph-users&#64;ceph.io/">ceph-users 邮件列表存档</a> 搜索。
如果没有明确修复或已经发现的缺陷，那就 <a class="reference internal" href="../../../start/get-involved/#get-involved"><span class="std std-ref">把这个问题报告给 ceph-devel
邮件列表</span></a> 。</p>
</section>
<section id="no-free-drive-space">
<span id="id11"></span><h3>硬盘没剩余空间<a class="headerlink" href="#no-free-drive-space" title="Permalink to this heading"></a></h3>
<p>如果某一个 OSD 满了， Ceph 为防止数据丢失，会确保不再向 OSD 写入新数据。
在健康运行着的集群中，当 OSD 们和存储池接近设置的“占满”比率时，就会产生健康警告。
<code class="docutils literal notranslate"><span class="pre">mon_osd_full_ratio</span></code> 阈值默认是 <code class="docutils literal notranslate"><span class="pre">0.95</span></code> （或容量的 95% ）：
这就是那个点，超过时客户端们就不能再写入数据了；
<code class="docutils literal notranslate"><span class="pre">mon_osd_backfillfull_ratio</span></code> 阈值默认为 <code class="docutils literal notranslate"><span class="pre">0.90</span></code> （或容量的 90% ）：
这就是那个点，超过时就不会启动回填。
<code class="docutils literal notranslate"><span class="pre">mon_osd_nearfull_ratio</span></code> 阈值默认为 <code class="docutils literal notranslate"><span class="pre">0.85</span></code> （或容量的 85% ）：
这就是那个点，达到时它会产生 <code class="docutils literal notranslate"><span class="pre">OSD_NEARFULL</span></code> 健康警告。</p>
<p>Ceph 集群内的 OSD 们分配到的数据量可能差别很大。
要检查“有多满”，可以显示出每个 OSD 的数据利用率，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>df</span>
</pre></div></div><p>要检查整个集群“有多满”，可以显示它的总体利用率、
和各存储池的数据分布，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>df</span>
</pre></div></div><p>检查 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">df</span></code> 命令的输出时，特别留意一下
<strong>最满</strong> 的 OSD 们，而不是原始空间的利用率。
只要有一个突兀的 OSD 被填满，就会导致它所在存储池的所有写入失败。
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">df</span></code> 报告存储池的可用空间时，考虑了指定存储池里相对 <em>最满</em> OSD 的比率设置。
要使数据分布更加均匀，有两种方法：
(1) 用 <code class="docutils literal notranslate"><span class="pre">reweight-by-utilization</span></code> 命令逐步地把数据从过满的 OSD 移到不太满的 OSD 上；
(2) 在 Luminous 后来的修订版和后续版本上，可以试着用
<code class="docutils literal notranslate"><span class="pre">ceph-mgr</span></code> <code class="docutils literal notranslate"><span class="pre">balancer</span></code> 模块来自动地执行这个任务。</p>
<p>要调整这个“占满”比率，
执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>set-nearfull-ratio<span class="w"> </span>&lt;float<span class="o">[</span><span class="m">0</span>.0-1.0<span class="o">]</span>&gt;</span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>set-full-ratio<span class="w"> </span>&lt;float<span class="o">[</span><span class="m">0</span>.0-1.0<span class="o">]</span>&gt;</span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>set-backfillfull-ratio<span class="w"> </span>&lt;float<span class="o">[</span><span class="m">0</span>.0-1.0<span class="o">]</span>&gt;</span>
</pre></div></div><p>有时候，集群出现用满的问题是由于一个 OSD 发生故障。
发生此问题，原因要么是测试、要么是集群很小、很满、或者不均衡。
当某一 OSD 或节点存储着很大比例的集群数据时，
组件故障甚或自然增长就能诱发 <code class="docutils literal notranslate"><span class="pre">nearfull</span></code> 和 <code class="docutils literal notranslate"><span class="pre">full</span></code> 比率超额。
如果你在小型集群上测试 Ceph 如何应对 OSD 故障，
建议留出足够的空闲空间，并且考虑临时降低 OSD 的
<code class="docutils literal notranslate"><span class="pre">full</span> <span class="pre">ratio</span></code> 、 <code class="docutils literal notranslate"><span class="pre">backfillfull</span> <span class="pre">ratio</span></code> 和
OSD <code class="docutils literal notranslate"><span class="pre">nearfull</span> <span class="pre">ratio</span></code> 的值。</p>
<p>OSD 的“占满”情况在 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">health</span></code> 的输出中能看到，
如下例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>health</span>
</pre></div></div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">HEALTH_WARN</span> <span class="mi">1</span> <span class="n">nearfull</span> <span class="n">osd</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</pre></div>
</div>
<p>要看细节，再加上 <code class="docutils literal notranslate"><span class="pre">detail</span></code> 命令，如下例：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>health<span class="w"> </span>detail</span>
</pre></div></div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">HEALTH_ERR</span> <span class="mi">1</span> <span class="n">full</span> <span class="n">osd</span><span class="p">(</span><span class="n">s</span><span class="p">);</span> <span class="mi">1</span> <span class="n">backfillfull</span> <span class="n">osd</span><span class="p">(</span><span class="n">s</span><span class="p">);</span> <span class="mi">1</span> <span class="n">nearfull</span> <span class="n">osd</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">osd</span><span class="mf">.3</span> <span class="ow">is</span> <span class="n">full</span> <span class="n">at</span> <span class="mi">97</span><span class="o">%</span>
<span class="n">osd</span><span class="mf">.4</span> <span class="ow">is</span> <span class="n">backfill</span> <span class="n">full</span> <span class="n">at</span> <span class="mi">91</span><span class="o">%</span>
<span class="n">osd</span><span class="mf">.2</span> <span class="ow">is</span> <span class="n">near</span> <span class="n">full</span> <span class="n">at</span> <span class="mi">87</span><span class="o">%</span>
</pre></div>
</div>
<p>处理集群用满的最好方法就是增加新 OSD 扩容，
新增 OSD 后，集群就能把数据重分布到新存储器里。
搜索一下 <code class="docutils literal notranslate"><span class="pre">rados</span> <span class="pre">bench</span></code> 遗留的数据，它们在浪费空间。</p>
<p>如果因满载而导致旧的 FileStore OSD 不能启动，
你可以试着删除那个 OSD 上的一些归置组数据目录，
回收一些空间。</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>如果你准备从填满的 OSD 中删除某个归置组，
注意<strong>不要</strong>删除另一个 OSD 上的同名归置组目录，
否则<strong>你会丢数据</strong>。<strong>必须</strong>在多个 OSD 上保留至少一份数据副本。删除归置组目录是一种少见的极端干涉方法，轻易不要用。</p>
</div>
<p>详情见<a class="reference external" href="../../configuration/mon-config-ref">监视器配置参考</a>。</p>
</section>
</section>
<section id="id12">
<h2>OSD 龟速或无响应<a class="headerlink" href="#id12" title="Permalink to this heading"></a></h2>
<p>OSD 有时会龟速或无响应。解决这种常见问题时，
你应该先确保排除了其他故障的可能性，然后再深入性能问题。
例如，确保你的网络运行正常、且 OSD 在运行，
还要检查 OSD 是否被恢复流量拖住了。</p>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>在 Ceph Luminous 版以前， <code class="docutils literal notranslate"><span class="pre">up</span></code> 且 <code class="docutils literal notranslate"><span class="pre">in</span></code>
的 OSD 有时候不可用或很慢，因为恢复消耗了系统资源。
较新的版本解决了这个问题，能更好地处理恢复。</p>
</div>
<section id="id13">
<h3>网络问题<a class="headerlink" href="#id13" title="Permalink to this heading"></a></h3>
<p>作为一个分布式的存储系统， Ceph 要靠网络实现 OSD 互联、
复制、故障恢复、和周期性心跳。
联网问题会导致 OSD 延时和状态抖动，详情参见<a class="reference internal" href="#id25">状态抖动的 OSD</a> 。</p>
<p>确保 Ceph 进程和 Ceph 依赖的进程已建立连接、且在监听，
执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">netstat<span class="w"> </span>-a<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>ceph</span>
<span class="prompt1">netstat<span class="w"> </span>-l<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>ceph</span>
<span class="prompt1">sudo<span class="w"> </span>netstat<span class="w"> </span>-p<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>ceph</span>
</pre></div></div><p>检查网络统计信息，执行下列命令：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">netstat<span class="w"> </span>-s</span>
</pre></div></div></section>
<section id="id14">
<h3>驱动器配置<a class="headerlink" href="#id14" title="Permalink to this heading"></a></h3>
<p>一个 SAS 或 SATA 存储驱动器应该只用于一个 OSD ；
NVMe 驱动器可以轻松处理两个或更多。不过，如果有其它进程共享驱动器，读和写吞吐量会成为瓶颈。
这类进程包括：日志/元数据、操作系统、 Ceph 监视器、 <code class="docutils literal notranslate"><span class="pre">syslog</span></code> 日志、
其它 OSD 以及非 Ceph 进程。</p>
<p>Ceph 在日志记录<em>完成之后</em>才会确认写操作，
所以高速 SSD 有助于降低响应时间，
尤其是在用旧的 FileStore OSD 搭配 <code class="docutils literal notranslate"><span class="pre">XFS</span></code> 或 <code class="docutils literal notranslate"><span class="pre">ext4</span></code> 文件系统时。
相反， <code class="docutils literal notranslate"><span class="pre">Btrfs</span></code> 文件系统可以同时写入和记日志。
（然而还是得注意，我们不建议在生产环境下用 <code class="docutils literal notranslate"><span class="pre">Btrfs</span></code> 。）</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>给驱动器分区并不能改变总吞吐量或顺序读写上限。把日志分离到单独的分区有可能提升吞吐量，
但它最好位于另外一个物理驱动器。</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Reef 不支持 FileStore 。 Reef 之后的版本不支持 FileStore 。
任何提及 FileStore 的信息仅与 Ceph 的 Quincy 版本和 Quincy 之前的版本相关。</p>
</div>
</section>
<section id="id15">
<h3>坏扇区和碎片化硬盘<a class="headerlink" href="#id15" title="Permalink to this heading"></a></h3>
<p>检修下硬盘是否有坏块、碎片、和其它会导致性能急剧下降的错误。检查设备错误用得上的工具有 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 、 <code class="docutils literal notranslate"><span class="pre">syslog</span></code> 日志、和
<code class="docutils literal notranslate"><span class="pre">smartctl</span></code> （包含在 <code class="docutils literal notranslate"><span class="pre">smartmontools</span></code> 软件包里）。</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">smartmontools</span></code> 7.0 和后续版本可提供
NVMe 透传（ passthrough ）统计信息和 JSON 输出。</p>
</div>
</section>
<section id="id16">
<h3>监视器和 OSD 蜗居<a class="headerlink" href="#id16" title="Permalink to this heading"></a></h3>
<p>虽然监视器是相对轻量的进程，但它们与 OSD
共存于同一台主机时，仍然可能产生性能问题。
监视器会发出大量 <code class="docutils literal notranslate"><span class="pre">fsync()</span></code> 系统调用，这会妨碍别的工作负载，
特别是监视器和 OSD 共享驱动器时，性能问题更严重。
另外，如果监视器基于较老的内核（低于3.0）、
或者不支持 <code class="docutils literal notranslate"><span class="pre">syncfs(2)</span></code> 系统调用的内核运行，
那么，同一主机上运行着的多个 OSD 会发出大量提交，导致相互拖累。这种情况有时会导致“爆发写”。</p>
</section>
<section id="id17">
<h3>进程蜗居<a class="headerlink" href="#id17" title="Permalink to this heading"></a></h3>
<p>与 OSD 们共存于同一套硬件上、并向 Ceph （例如，基于云的解决方案、
虚拟机）写入数据的进程，可能会导致 OSD 延时明显增大。
正因为如此，所以一般不建议让这样的进程与 OSD 共存。
相反，我们建议对用于 Ceph 的主机做特别优化、
并用另外一些主机跑其它进程。实践证明，
把 Ceph 操作和其他应用程序分开可提高性能、
并简化故障排除和运维。</p>
<p>在同一套硬件上运行共存进程有时叫做“融合（ convergence ）”。
在使用 Ceph 时，只有具备了专业知识并经过深思熟虑后才能进行融合。</p>
</section>
<section id="id18">
<h3>日志记录级别<a class="headerlink" href="#id18" title="Permalink to this heading"></a></h3>
<p>高日志级别会导致性能问题。
操作员有时为追踪某问题提高了日志级别、但结束后忘了调回去。
此时， OSD 们就可能浪费宝贵的系统资源，
向硬盘写入大量没必要的详细日志。如果你想始终保持高日志级别，
可以考虑给默认日志路径挂载个硬盘（比如 <code class="docutils literal notranslate"><span class="pre">/var/log/ceph/$cluster-$name.log</span></code> ）。</p>
</section>
<section id="id19">
<h3>恢复节流<a class="headerlink" href="#id19" title="Permalink to this heading"></a></h3>
<p>根据你的配置， Ceph 可以降低恢复速度来维持客户端或 OSD 性能，
或者，可以不顾客户端或 OSD 性能而加快恢复速度。
检查下客户端或 OSD 是否正在恢复。</p>
</section>
<section id="id20">
<h3>内核版本<a class="headerlink" href="#id20" title="Permalink to this heading"></a></h3>
<p>检查下你在用的内核版本。较老的内核也许没有移植能提高 Ceph 性能的功能。</p>
</section>
<section id="syncfs">
<h3>与 SyncFS 相关的内核问题<a class="headerlink" href="#syncfs" title="Permalink to this heading"></a></h3>
<p>如果你遇到了与 SyncFS 相关的内核问题，试试在一主机上只运行一个 OSD ，
看看性能是否有提升。老内核未必支持有 <code class="docutils literal notranslate"><span class="pre">syncfs(2)</span></code> 系统调用的新版 <code class="docutils literal notranslate"><span class="pre">glibc</span></code> 。</p>
</section>
<section id="id21">
<h3>文件系统问题<a class="headerlink" href="#id21" title="Permalink to this heading"></a></h3>
<p>在 Luminous 版以后，我们建议用 BlueStore 后端部署集群。
运行 Luminous 之前的版本、或由于某些原因还得用之前的 FileStore 后端部署 OSD 时，我们推荐 <code class="docutils literal notranslate"><span class="pre">XFS</span></code> 。</p>
<p>我们不推荐用 <code class="docutils literal notranslate"><span class="pre">Btrfs</span></code> 或 <code class="docutils literal notranslate"><span class="pre">ext4</span></code> 。 <code class="docutils literal notranslate"><span class="pre">Btrfs</span></code> 有很多诱人的功能，
但文件系统自身的缺陷可能导致性能问题，以及 ENOSPC 伪错误。
我们不建议使用 <code class="docutils literal notranslate"><span class="pre">ext4</span></code> 做 OSD 的 FileStore ，因为其 <code class="docutils literal notranslate"><span class="pre">xattr</span></code> 尺寸限制会破坏我们对长对象名的支持，而这是 RGW 必需的。</p>
<p>详情见<a class="reference external" href="../configuration/filesystem-recommendations">文件系统推荐</a>。</p>
</section>
<section id="id23">
<h3>内存不足<a class="headerlink" href="#id23" title="Permalink to this heading"></a></h3>
<p>我们建议给每个 OSD 守护进程 <em>最少</em> 4GB 内存，而且建议在 6-8GB 之上取整。
你也许注意到了，日常操作中 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 进程仅会用其中一小部分。
你也许想用这些空闲内存同时跑一些其他应用、或者克扣各节点的内存容量。然而当 OSD 在恢复时，其内存使用会激增，
如果恢复期间内存不够充足， OSD 的性能将明显降低，
而且守护进程们甚至会崩溃或被 Linux 的 <code class="docutils literal notranslate"><span class="pre">OOM</span> <span class="pre">Killer</span></code> 杀死。</p>
</section>
<section id="blocked-requests-slow-requests">
<h3>Blocked Requests 或 Slow Requests 问题<a class="headerlink" href="#blocked-requests-slow-requests" title="Permalink to this heading"></a></h3>
<p>如果某个 <code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 守护进程对一个请求的响应很慢，
集群日志系统会收到消息，
报告出耗时过于长的那些操作。默认警告阀值是 30 秒，可以用 <code class="docutils literal notranslate"><span class="pre">osd_op_complaint_time</span></code> 选项来配置。</p>
<p>Ceph 的老旧版本会抱怨 <code class="docutils literal notranslate"><span class="pre">old</span> <span class="pre">requests</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">osd</span><span class="mf">.0</span> <span class="mf">192.168.106.220</span><span class="p">:</span><span class="mi">6800</span><span class="o">/</span><span class="mi">18813</span> <span class="mi">312</span> <span class="p">:</span> <span class="p">[</span><span class="n">WRN</span><span class="p">]</span> <span class="n">old</span> <span class="n">request</span> <span class="n">osd_op</span><span class="p">(</span><span class="n">client</span><span class="mf">.5099.0</span><span class="p">:</span><span class="mi">790</span> <span class="n">fatty_26485_object789</span> <span class="p">[</span><span class="n">write</span> <span class="mi">0</span><span class="o">~</span><span class="mi">4096</span><span class="p">]</span> <span class="mf">2.5e54</span><span class="n">f643</span><span class="p">)</span> <span class="n">v4</span> <span class="n">received</span> <span class="n">at</span> <span class="mi">2012</span><span class="o">-</span><span class="mi">03</span><span class="o">-</span><span class="mi">06</span> <span class="mi">15</span><span class="p">:</span><span class="mi">42</span><span class="p">:</span><span class="mf">56.054801</span> <span class="n">currently</span> <span class="n">waiting</span> <span class="k">for</span> <span class="n">sub</span> <span class="n">ops</span>
</pre></div>
</div>
<p>较新版本的 Ceph 抱怨 <code class="docutils literal notranslate"><span class="pre">slow</span> <span class="pre">requests</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">date</span><span class="p">}</span> <span class="p">{</span><span class="n">osd</span><span class="o">.</span><span class="n">num</span><span class="p">}</span> <span class="p">[</span><span class="n">WRN</span><span class="p">]</span> <span class="mi">1</span> <span class="n">slow</span> <span class="n">requests</span><span class="p">,</span> <span class="mi">1</span> <span class="n">included</span> <span class="n">below</span><span class="p">;</span> <span class="n">oldest</span> <span class="n">blocked</span> <span class="k">for</span> <span class="o">&gt;</span> <span class="mf">30.005692</span> <span class="n">secs</span>
<span class="p">{</span><span class="n">date</span><span class="p">}</span> <span class="p">{</span><span class="n">osd</span><span class="o">.</span><span class="n">num</span><span class="p">}</span>  <span class="p">[</span><span class="n">WRN</span><span class="p">]</span> <span class="n">slow</span> <span class="n">request</span> <span class="mf">30.005692</span> <span class="n">seconds</span> <span class="n">old</span><span class="p">,</span> <span class="n">received</span> <span class="n">at</span> <span class="p">{</span><span class="n">date</span><span class="o">-</span><span class="n">time</span><span class="p">}:</span> <span class="n">osd_op</span><span class="p">(</span><span class="n">client</span><span class="mf">.4240.0</span><span class="p">:</span><span class="mi">8</span> <span class="n">benchmark_data_ceph</span><span class="o">-</span><span class="mi">1_39426</span><span class="n">_object7</span> <span class="p">[</span><span class="n">write</span> <span class="mi">0</span><span class="o">~</span><span class="mi">4194304</span><span class="p">]</span> <span class="mf">0.69848840</span><span class="p">)</span> <span class="n">v4</span> <span class="n">currently</span> <span class="n">waiting</span> <span class="k">for</span> <span class="n">subops</span> <span class="kn">from</span> <span class="p">[</span><span class="mi">610</span><span class="p">]</span>
</pre></div>
</div>
<p>可能的起因有：</p>
<ul class="simple">
<li><p>快要坏的驱动器（查验一下 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 输出）；</p></li>
<li><p>内核文件系统缺陷（查验一下 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 输出）；</p></li>
<li><p>集群过载（检查系统负载、 iostat 等等）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ceph-osd</span></code> 守护进程缺陷。</p></li>
<li><p>OSD 分片配置不是最优（在基于 HDD 的集群上采用 mClock 调度器）</p></li>
</ul>
<p>可能的解决方法：</p>
<ul class="simple">
<li><p>从 Ceph 主机去除 VM ；</p></li>
<li><p>升级内核；</p></li>
<li><p>升级 Ceph ；</p></li>
<li><p>重启 OSD 。</p></li>
<li><p>替换坏的或快要坏的组件；</p></li>
<li><dl class="simple">
<dt>覆盖 OSD 分片配置（在基于 HDD 的集群上采用 mClock 调度器）</dt><dd><ul>
<li><p>参阅 <a class="reference internal" href="#mclock-tblshoot-hdd-shard-config"><span class="std std-ref">采用 mClock 调度器时的 Slow Requests 或者 Slow Recovery</span></a> 获取解决方案</p></li>
</ul>
</dd>
</dl>
</li>
</ul>
</section>
<section id="id24">
<h3>慢请求的调试<a class="headerlink" href="#id24" title="Permalink to this heading"></a></h3>
<p>运行 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">daemon</span> <span class="pre">osd.&lt;id&gt;</span> <span class="pre">dump_historic_ops</span></code> 或
<code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">daemon</span> <span class="pre">osd.&lt;id&gt;</span> <span class="pre">dump_ops_in_flight</span></code> 命令时，
你会看到一堆操作和各个操作过程的一个事件列表，下面简单说明一下。</p>
<p>信使层事件：</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">header_read</span></code>: 信使首次从线路读取到消息的时间；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">throttled</span></code>: 信使尝试申请内存节流空间、用于把消息读入内存的时间；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">all_read</span></code>: 信使从线路读取出消息，完成的时间；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">dispatched</span></code>: 信使把消息发给 OSD 的时间；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">initiated</span></code>: 等价于 <code class="docutils literal notranslate"><span class="pre">header_read</span></code> ，这二者都保留着是历史遗留问题。</p></li>
</ul>
<p>OSD 处理 ops （操作）时的事件：</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">queued_for_pg</span></code>: op 已放入队列，等着它自己的 PG 来处理；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">reached_pg</span></code>: 其 PG 已开始执行这个 op ；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">waiting</span> <span class="pre">for</span> <span class="pre">\*</span></code>: 此 op 正等着某些其它工作结束，这样它才能继续下一步（如，一个新 OSDMap ；等着这个对象目标完成洗刷；
等着相应的 PG 完成互联；所有都在消息内指出了）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">started</span></code>: 此 op 已被这个 OSD 接受为应该做的事，
并且正在进行中；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">waiting</span> <span class="pre">for</span> <span class="pre">subops</span> <span class="pre">from</span></code>: 此 op 已发送给了副本 OSD 们。</p></li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">FileStore</span></code> 事件:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">commit_queued_for_journal_write</span></code>: 此 op 已递送给了 FileStore 。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">write_thread_in_journal_buffer</span></code>: 此 op 已经在日志的缓冲中了、
并等着持久化（等着下一次硬盘写操作）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">journaled_completion_queued</span></code>: 此 op 已在硬盘上作了日志、且它的回调已进入队列等着被调用了。</p></li>
</ul>
<p>数据已传递给更底层存储之后的 OSD 事件：</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">op_commit</span></code>: 此 op 已被主 OSD 提交
（即已写入日志）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">op_applied</span></code>: 此 op <a class="reference external" href="https://www.freebsd.org/cgi/man.cgi?write(2)">已经用 write() 写入</a>
主 OSD 的后端文件系统（即在内存里已应用，但还没刷入硬盘）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_op_applied</span></code>: （类似前面的） <code class="docutils literal notranslate"><span class="pre">op_applied</span></code> ，但这是发生在副本上的 subop （子操作）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_op_committed</span></code>: 就是 <code class="docutils literal notranslate"><span class="pre">op_commit</span></code> ，但这是发生在副本上的 subop （仅发生在 EC 存储池中）；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_op_commit_rec/sub_op_apply_rec</span> <span class="pre">from</span> <span class="pre">&lt;X&gt;</span></code>: 主 OSD 得知上述消息后会做这些标记，只是为某个特定副本（即 <code class="docutils literal notranslate"><span class="pre">&lt;X&gt;</span></code> ）做标记；</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">commit_sent</span></code>: 我们已经把回信发给客户端（或主 OSD ，来自子操作的）了。</p></li>
</ul>
<p>这些事件里，有很多看起来显得多余，但都是代码里穿越重要边界的（像数据加锁后传入新线程）。</p>
</section>
<section id="mclock-slow-requests-slow-recovery">
<span id="mclock-tblshoot-hdd-shard-config"></span><h3>采用 mClock 调度器时的 Slow Requests 或者 Slow Recovery<a class="headerlink" href="#mclock-slow-requests-slow-recovery" title="Permalink to this heading"></a></h3>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>此故障排除仅适针对：使用 HDD 、且采用了 mClock 调度器、
并具有以下 OSD 分片配置： <code class="docutils literal notranslate"><span class="pre">osd_op_num_shards_hdd</span></code> = 5 且
<code class="docutils literal notranslate"><span class="pre">osd_op_num_threads_per_shard_hdd</span></code> = 1 。此外，参阅 <a class="reference internal" href="../../configuration/mclock-config-ref/#mclock-hdd-cfg"><span class="std std-ref">OSD Shard Configuration For HDD Based Clusters With mClock</span></a> ，
了解采用 mClock 时需要对默认的 OSD HDD 分片配置做更改的原因。</p>
</div>
<p>在启用了 mClock 调度器的、基于硬盘扩展的集群上，有多个 OSD 节点故障的条件下，
可能会报告或观察到以下情况：</p>
<ul class="simple">
<li><p>slow requests （请求变慢）: 这也会导致客户端 I/O 性能下降。</p></li>
<li><p>slow background recoveries （后台恢复变慢）: 低于应有的恢复流量。</p></li>
</ul>
<p><strong>故障排除步骤：</strong></p>
<ol class="arabic simple">
<li><p>从 OSD 事件中核实 “slow requests” 主要属于
<code class="docutils literal notranslate"><span class="pre">queued_for_pg</span></code> 类型。</p></li>
<li><p>在 QoS 对后台恢复服务能有效管理的情况下，
验证报告的恢复速率是否远低于预期速率。</p></li>
</ol>
<p>如果上述任一步骤属实，那就可以采用以下解决方案。
注意，这会造成中断，因为需要重新启动 OSD 。
运行以下命令更改硬盘的默认 OSD 分片配置：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>osd<span class="w"> </span>osd_op_num_shards_hdd<span class="w"> </span><span class="m">1</span></span>
<span class="prompt1">ceph<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>osd<span class="w"> </span>osd_op_num_threads_per_shard_hdd<span class="w"> </span><span class="m">5</span></span>
</pre></div></div><p>上述配置不会立即生效，并且需要重启此环境中的 OSD 。
为使这一过程的破坏性最小，可谨慎地交错重启 OSD 。</p>
</section>
</section>
<section id="rados-tshooting-flapping-osd">
<span id="id25"></span><h2>状态抖动的 OSD<a class="headerlink" href="#rados-tshooting-flapping-osd" title="Permalink to this heading"></a></h2>
<p>“状态抖动”（打摆子）是指 OSD 的一种情形，快速地、接二连三地被反复标记为 <code class="docutils literal notranslate"><span class="pre">up</span></code> 而后 <code class="docutils literal notranslate"><span class="pre">down</span></code> 的现象。
本节将解释如何识别抖动，以及如何缓解抖动。</p>
<p>OSD 们互联和检查心跳时会优先选集群网（后端），
详情见<a class="reference external" href="../../configuration/mon-osd-interaction">监视器与 OSD 的交互</a>。</p>
<p>上游的 Ceph 社区传统上一直建议拆分 <em>公共</em> (前端）和 <em>私密</em>
（集群、后端、复制）网络，因为这样有如下好处：</p>
<ol class="arabic simple">
<li><p>隔离 (1) 心跳流量、复制流量、恢复流量（私网）与
(2) 客户端流量、 OSD 间流量、监视器流量（公网）。
这样有助于防范另一边发生的 DoS 攻击，
但同样也可能导致连锁故障。</p></li>
<li><p>公网和私网流量都会有额外吞吐量。</p></li>
</ol>
<p>过去，常用的网络速率是以 100Mb/s 和 1Gb/s 来衡量的，
这样的隔离通常是必要的。
但如今用上了 10Gb/s 、 40Gb/s 和 25/50/100Gb/s 的网络，
以往对于容量的关注一般就减少甚至不存在了。
比如，你的 OSD 节点都有 2 个网口，
一个接公网、另一个接私网，就意味着没有线路冗余。
这样降低了你在不影响集群和客户端的前提下、
容忍网络维护和故障的能力。试想一下，
如果两条链路都用于公网：
采用端口绑定（ LACP ）或等价路由（如 FRR ），
有利于增加的吞吐量空间、容错性、并减少 OSD 抖动。</p>
<p>当私网（甚至是单条主机链路）发生故障、或降级，同时，公网却正常运行， OSD 就可能无法恰当地处理这种情况。
在这种情况下， OSD 们会用公网向监视器报告彼此 <code class="docutils literal notranslate"><span class="pre">down</span></code> 了、同时把它自己标记为 <code class="docutils literal notranslate"><span class="pre">up</span></code> 的。然后监视器们就再次向公网散播更新过的集群运行图，
此图把受影响的 OSD 们标记成了 <cite>down</cite> ，这些 OSD 们又向监视器反馈“我还没死呢！”，如此循环往复。我们把这种情形称为 “状态抖动” （或打摆子， flapping ），
而且它很难隔离和矫正。如果没有私网，就避免了这种讨厌的动态：
OSD 们通常要么是 <code class="docutils literal notranslate"><span class="pre">up</span></code> 要么是 <code class="docutils literal notranslate"><span class="pre">down</span></code> ，没有抖动。</p>
<p>如果有东西导致 OSD 状态抖动（反复地被标记为 <code class="docutils literal notranslate"><span class="pre">down</span></code> ，
而后又 <code class="docutils literal notranslate"><span class="pre">up</span></code> ），你可以临时冻结它们的状态，
强制监视器们暂停打摆子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">set</span><span class="w"> </span>noup<span class="w">      </span><span class="c1"># prevent OSDs from getting marked up</span></span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">set</span><span class="w"> </span>nodown<span class="w">    </span><span class="c1"># prevent OSDs from getting marked down</span></span>
</pre></div></div><p>这些标记会记录在 osdmap 里：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span>dump<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>flags</span>
</pre></div></div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">flags</span> <span class="n">no</span><span class="o">-</span><span class="n">up</span><span class="p">,</span><span class="n">no</span><span class="o">-</span><span class="n">down</span>
</pre></div>
</div>
<p>下列命令可清除标记：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">unset</span><span class="w"> </span>noup</span>
<span class="prompt1">ceph<span class="w"> </span>osd<span class="w"> </span><span class="nb">unset</span><span class="w"> </span>nodown</span>
</pre></div></div><p>还支持其它两个标记 <code class="docutils literal notranslate"><span class="pre">noin</span></code> 和 <code class="docutils literal notranslate"><span class="pre">noout</span></code> ，
它们分别可防止正在启动的 OSD 被标记为 <code class="docutils literal notranslate"><span class="pre">in</span></code> （已分配数据）、
或防止 OSD 被误标记为 <code class="docutils literal notranslate"><span class="pre">out</span></code>
（不管 <code class="docutils literal notranslate"><span class="pre">mon</span> <span class="pre">osd</span> <span class="pre">down</span> <span class="pre">out</span> <span class="pre">interval</span></code> 当前的值是什么）。</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">noup</span></code> 、 <code class="docutils literal notranslate"><span class="pre">noout</span></code> 和 <code class="docutils literal notranslate"><span class="pre">nodown</span></code> 从某种意义上说是临时的，
一旦标记清除了，它们被阻塞的动作短时间内就会发生；相反， <code class="docutils literal notranslate"><span class="pre">noin</span></code> 标记是阻止 OSD 启动后进入集群
（被标记为 <code class="docutils literal notranslate"><span class="pre">in</span></code> ），但其它所有设置标记前就已经启动了的守护进程们都维持原样。</p>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>打摆子的起因和影响有时候可以通过仔细地调整
<code class="docutils literal notranslate"><span class="pre">mon_osd_down_out_subtree_limit</span></code> 、
<code class="docutils literal notranslate"><span class="pre">mon_osd_reporter_subtree_level</span></code> 、和
<code class="docutils literal notranslate"><span class="pre">mon_osd_min_down_reporters</span></code> 来消除。
最优配置的偏离取决于集群大小、拓扑结构、和在用的 Ceph 版本。
它们之间的相互影响很微妙，超出了本文档的范围。</p>
</div>
</section>
</section>



<div id="support-the-ceph-foundation" class="admonition note">
  <p class="first admonition-title">Brought to you by the Ceph Foundation</p>
  <p class="last">The Ceph Documentation is a community resource funded and hosted by the non-profit <a href="https://ceph.io/en/foundation/">Ceph Foundation</a>. If you would like to support this and our other efforts, please consider <a href="https://ceph.io/en/foundation/join/">joining now</a>.</p>
</div>


           </div>
           
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="../troubleshooting-mon/" class="btn btn-neutral float-left" title="监视器故障排除" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="../troubleshooting-pg/" class="btn btn-neutral float-right" title="归置组排障" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).</p>
  </div>

   

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>